package com.aws.server;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.gson.Gson;

@SuppressWarnings("serial")
public class StaticDataTownServlet extends HttpServlet {
	
	static HashMap<String,Town> ds = new HashMap<String,Town>();

	public void doGet (HttpServletRequest req, HttpServletResponse res)
			throws ServletException, IOException {
		process(req,res);
	}
	public void doPost(HttpServletRequest req, HttpServletResponse res)
			throws ServletException, IOException {
		process(req,res);
	}
	public void doPut (HttpServletRequest req, HttpServletResponse res)
			throws ServletException, IOException {

		process(req,res);
	}
	public void doDelete (HttpServletRequest req, HttpServletResponse res)
			throws ServletException, IOException {
		process(req,res);
	}
	
	public void process (HttpServletRequest req, HttpServletResponse res)
			throws ServletException, IOException {
	
		PrintWriter out = res.getWriter();
		
		String method = req.getMethod();
		String path = req.getPathInfo();
	
		System.out.println(req.getRequestURI() + " : ["+method+"|"+path+"] ");		

		if (path != null){

			String[] pathComponents = path.split("/");
			String resource = pathComponents[1];
			
			System.out.println("Single action over resource '"+resource+"'");		

			processResource(method, pathComponents[1] , req, res);

		}else{
			System.out.println("Action over the list of resources");		
			processResourceList(method, req, res);
		}
		
		out.close();
	}
	
	
	@SuppressWarnings("static-access")
	private void processResourceList(String method, HttpServletRequest req,
			HttpServletResponse res) throws IOException {
		
		switch (method){
			case "POST" : postTown(req,res); break;
	
			case "PUT" : res.setStatus(res.SC_METHOD_NOT_ALLOWED); break;
	
			case "GET" : getTowns(req,res); break;
	
			case "DELETE" : ds.clear();	 break;
	
		}
	}

	@SuppressWarnings("static-access")
	private void postTown(HttpServletRequest req, HttpServletResponse res) throws IOException {
		
		Town t = extractTown(req);
		
		if(t == null)
			res.setStatus(res.SC_BAD_REQUEST);
		else if(ds.containsKey(t.name))
			res.setStatus(res.SC_CONFLICT);
		else
			ds.put(t.name, t);
		
	}
	
	private void getTowns(HttpServletRequest req, HttpServletResponse res) throws IOException {

		Gson gson = new Gson();
	
		//TEST DATA: if (ds.size() == 0) ds.put("Sevilla", new Town("Sevilla",700000));
		
		String jsonString = gson.toJson(ds.values());
		
		res.getWriter().println(jsonString);
		
	}		
		


	@SuppressWarnings("static-access")
	private void processResource(String method, String resource,
			HttpServletRequest req, HttpServletResponse res) throws IOException {

		if(method == "POST"){
			res.setStatus(res.SC_METHOD_NOT_ALLOWED);
			return;
		}
		
		if(!ds.containsKey(resource)){
			res.setStatus(res.SC_NOT_FOUND);
			return;
		}
		
		switch (method){
	
			case "PUT" : updateTown(resource,req,res); break;
	
			case "GET" : getTown(resource, req,res); break;
	
			case "DELETE" : ds.remove(resource); break;				
		}
		
	}
	
	@SuppressWarnings("static-access")
	private void updateTown(String resource, HttpServletRequest req, HttpServletResponse res) throws IOException {
		
		Town t = extractTown(req);
		
		if(t == null)
			res.setStatus(res.SC_BAD_REQUEST);
		else if(t.name != resource)
			res.setStatus(res.SC_FORBIDDEN);
		else
			ds.put(t.name, t);		
	}
	
	private void getTown(String resource, HttpServletRequest req, HttpServletResponse res) throws IOException {

		Gson gson = new Gson();
		
		String jsonString = gson.toJson(ds.get(resource));
		
		res.getWriter().println(jsonString);
		
	}
	

	private Town extractTown(HttpServletRequest req) throws IOException {

		Town t = null;
		Gson gson = new Gson();
		StringBuilder sb = new StringBuilder();
	    BufferedReader br = req.getReader();
	    
	    String jsonString;
	    while( (jsonString = br.readLine()) != null ){
	        sb.append(jsonString);
	    }    
	    jsonString = sb.toString();
	    
	    try{
	    	System.out.println("String to be parsed: <"+jsonString+">");
	    	t = gson.fromJson(jsonString, Town.class);
	    	System.out.println("Town extracted: "+t+" (name = '"+t.name+ "')");
	    }catch(Exception e){
	    	System.out.println("ERROR parsing Town: "+e.getMessage());
	    }
		
		return t;
	}
	
}
